package com.tianci.appstore.ui.detail;

import android.content.Context;
import android.graphics.Bitmap;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils.TruncateAt;
import android.view.Gravity;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.coocaa.x.framework.app.CoocaaApplication;
import com.coocaa.x.framework.utils.LogUtils;
import com.tianci.appstore.R;
import com.tianci.appstore.ui.SkinManager;
import com.tianci.appstore.ui.data.SkyAppDetailData;
import com.tianci.appstore.ui.data.SkyAppDetailData.AppStatus;
import com.tianci.appstore.ui.detail.ShotsScrollView.ShotLoseFocusListener;
import com.tianci.appstore.ui.detail.dialog.IntroductionDialog;
import com.tianci.appstore.ui.detail.dialog.ShotDialog;
import com.tianci.appstore.ui.detail.dialog.ShotDialog.PreviewListener;
import com.tianci.appstore.ui.loading.LoadingView;
import com.tianci.appstore.ui.util.UICommon;
import com.tianci.appstore.ui.widget.AlwaysMarqueeTextView;
import com.tianci.appstore.ui.widget.CatchImageView;
import com.tianci.appstore.ui.widget.LeftImageButtonLayer;
import com.tianci.appstore.utils.ImageUtils;
import com.tianci.appstore.utils.SkyConstants;
import com.tianci.appstore.utils.SkyNetImageCache;
import com.tianci.appstore.utils.SkyNetImageCache.ImageLoadListener;

import java.util.List;

public class AppDetailView extends FrameLayout implements ImageLoadListener, PreviewListener,
        ShotLoseFocusListener {
    private Context context;
    private FrameLayout mainLayout;
    private FrameLayout upLeftLayout;
    private TextView tipText;
    private ImageView iconImage;
    private ImageView cornerIconImage;
    private TextView titleText;
    private LinearLayout infoLayout;
    private StatusIndicator statusIndicator;
    private TextView introductionText;
    private ShotsScrollView shotsScroll;
    private LeftImageButtonLayer mButtonLayer = null;
    private int upWidth = SkyConstants.Div(924);
    private int upHeight = SkyConstants.Div(431);
    private int titleTextSize = SkyConstants.Dpi(35);
    private int infoTextSize = SkyConstants.Dpi(30);
    private int shortInfoWidth = SkyConstants.Div(363);
    private int longInfoWidth = SkyConstants.Div(573);

    private final int maxInfoSize = 5;
    public static final int MAX_SHOT_COUNT = 5;

    private SkyAppDetailData data;
    private static final int UPDATE_ICON = 0;
    private static final int UPDATE_CORNER_ICON = 1;
    private static final int UPDATE_SHOT_PREVIEW = 2;
    private static final int UPDATE_SHOT_BIG = 3;

    private Bitmap iconBitmap;

    private LoadingView loadingView;

    private static int iconLeftMargin = SkyConstants.Div(140);
    private static int iconTopMargin = SkyConstants.Div(150);
    private boolean mDestory = false;
    protected Bitmap cornerBitmap;

    public AppDetailView(Context context) {
        super(context);
        this.context = context;
        createView();
        setLoadingVisible(true);
    }

    private void createView() {
        SkinManager.setBackground(this, R.drawable.ui_sdk_app_bg);
        mainLayout = new FrameLayout(context);
        this.addView(mainLayout, new LayoutParams(LayoutParams.MATCH_PARENT,
                LayoutParams.MATCH_PARENT));

        addButtonsLayer();
        initUpLayout();
        initIconTitle();
        initShotsLayout();
        initLoading();
        statusIndicator.initFocus();
        mainLayout.setVisibility(View.INVISIBLE);
    }

    private void initUpLayout() {
        upLeftLayout = new FrameLayout(context);
        SkinManager.setBackground(upLeftLayout, R.drawable.detail_block_bg);

        infoLayout = new LinearLayout(context);
        infoLayout.setOrientation(LinearLayout.VERTICAL);
        infoLayout.setGravity(Gravity.LEFT);
        LayoutParams infoParams = new LayoutParams(longInfoWidth, SkyConstants.Div(252));
        infoParams.leftMargin = SkyConstants.Div(81);
        infoParams.topMargin = SkyConstants.iconWidth / 2 + SkyConstants.Div(33);
        upLeftLayout.addView(infoLayout, infoParams);

        statusIndicator = new StatusIndicator(context);
        LayoutParams statusParams = new LayoutParams(LayoutParams.WRAP_CONTENT,
                LayoutParams.MATCH_PARENT, Gravity.RIGHT | Gravity.BOTTOM);
        statusParams.rightMargin = SkyConstants.Div(30);
        statusParams.bottomMargin = SkyConstants.Div(30);
        upLeftLayout.addView(statusIndicator, statusParams);

        introductionText = new TextView(context);
        introductionText.setFocusable(true);
        introductionText.setSingleLine(false);
        introductionText.setId(122);
        introductionText.setNextFocusRightId(introductionText.getId());
        introductionText.setLineSpacing(SkyConstants.blockSpacing, 1.0f);
        introductionText.setMaxLines(6);
        introductionText.setTextSize(infoTextSize);
        introductionText.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
        introductionText.setEllipsize(TruncateAt.END);
        introductionText.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                if (introDialog == null) {
                    introDialog = new IntroductionDialog(context);
                }
                introDialog.setContent(iconBitmap, titleText.getText().toString(), introductionText
                        .getText().toString());
                introDialog.show();
            }
        });
        SkinManager.setTextColor(introductionText, R.color.titleColor);
        SkinManager.setBackground(introductionText, R.drawable.block_bg);
        final int textPadding = SkyConstants.Div(80);
        introductionText.setPadding(textPadding, textPadding, textPadding, textPadding);
        introductionText.setOnFocusChangeListener(new OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                // TODO Auto-generated method stub
                if (hasFocus)
                    SkinManager.setBackground(v, R.drawable.block_focused);
                else
                    SkinManager.setBackground(v, R.drawable.block_bg);
                v.setPadding(textPadding, textPadding, textPadding, textPadding);
            }
        });

        LinearLayout upLayout = new LinearLayout(context);
        upLayout.setGravity(Gravity.CENTER_VERTICAL);
        upLayout.addView(upLeftLayout, new LayoutParams(upWidth, upHeight));
        LinearLayout.LayoutParams introParams = new LinearLayout.LayoutParams(upWidth, upHeight);
        introParams.leftMargin = SkyConstants.Div(-46);
        upLayout.addView(introductionText, introParams);

        LayoutParams upParams = new LayoutParams(LayoutParams.WRAP_CONTENT,
                LayoutParams.WRAP_CONTENT, Gravity.CENTER);
        upParams.bottomMargin = SkyConstants.Div(129);
        mainLayout.addView(upLayout, upParams);
    }

    private void addButtonsLayer() {
        mButtonLayer = new LeftImageButtonLayer(context);
        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
                LayoutParams.WRAP_CONTENT, Gravity.RIGHT);
        params.setMargins(0, SkyConstants.Div(98), SkyConstants.Div(115), 0);
        mButtonLayer.setLayoutParams(params);
        mButtonLayer.initDefaultParams();
        mainLayout.addView(mButtonLayer);
    }

    private void initIconTitle() {
        LinearLayout iconTitleLayout = new LinearLayout(context);
        iconTitleLayout.setGravity(Gravity.CENTER_VERTICAL);

        iconImage = new CatchImageView(context);
        iconImage.setScaleType(ScaleType.FIT_XY);
        iconTitleLayout.addView(iconImage, new LinearLayout.LayoutParams(SkyConstants.iconWidth,
                SkyConstants.iconWidth));

        titleText = new AlwaysMarqueeTextView(context);
        SkinManager.setBackground(titleText, R.drawable.title_bg);
        titleText.setTextSize(titleTextSize);
        titleText.setMaxWidth(SkyConstants.Div(625));
        titleText.setGravity(Gravity.CENTER_VERTICAL);
        titleText.setPadding(SkyConstants.Div(36), 0, SkyConstants.Div(39), SkyConstants.Div(9));
        titleText.setVisibility(View.INVISIBLE);
        SkinManager.setTextColor(titleText, R.color.titleColor);
        LinearLayout.LayoutParams titleParams = new LinearLayout.LayoutParams(
                LayoutParams.WRAP_CONTENT, SkyConstants.Div(78));
        titleParams.leftMargin = SkyConstants.Div(24);
        titleParams.topMargin = SkyConstants.Div(7);
        iconTitleLayout.addView(titleText, titleParams);

        LayoutParams iconTitleParams = new LayoutParams(LayoutParams.WRAP_CONTENT,
                LayoutParams.WRAP_CONTENT);
        iconTitleParams.leftMargin = iconLeftMargin;
        iconTitleParams.topMargin = iconTopMargin;
        mainLayout.addView(iconTitleLayout, iconTitleParams);
    }

    private void initShotsLayout() {
        shotsScroll = new ShotsScrollView(context, this);
        shotsScroll.setImageClickListener(imageClickListener);
        shotsScroll.setShotLostFocusListener(this);
        LayoutParams shotParams = new LayoutParams(LayoutParams.WRAP_CONTENT,
                LayoutParams.WRAP_CONTENT, Gravity.CENTER);
        shotParams.topMargin = SkyConstants.Div(230);
        mainLayout.addView(shotsScroll, shotParams);
    }

    private void initLoading() {
        loadingView = new LoadingView(context);
        this.addView(loadingView, new LayoutParams(LayoutParams.MATCH_PARENT,
                LayoutParams.MATCH_PARENT));
        loadingView.setVisibility(View.INVISIBLE);
    }

    private void setLoadingVisible(boolean visible) {
        if (visible) {
            mainLayout.setVisibility(View.INVISIBLE);
            loadingView.startLoading();
        } else {
            loadingView.stopLoading();
            mainLayout.setVisibility(View.VISIBLE);
        }
    }

    private void initTipText() {
        if (tipText == null)
            tipText = UICommon.newTextView(context, UICommon.tipTextSize, R.color.tipColor);
        if (tipText.getParent() == null)
            this.addView(tipText, new LayoutParams(LayoutParams.WRAP_CONTENT,
                    LayoutParams.WRAP_CONTENT, Gravity.CENTER));
    }

    public void clearContent() {
        mainLayout.setVisibility(View.INVISIBLE);
        if (introDialog != null)
            introDialog.dismiss();
        if (shotDialog != null)
            shotDialog.dismiss();
        if (tipText != null)
            tipText.setVisibility(View.INVISIBLE);
    }

    public void update(SkyAppDetailData data) {
        if (data == null) {
            mainLayout.setVisibility(View.INVISIBLE);
            initTipText();
            tipText.setText(R.string.detail_failed_tip);
            tipText.setVisibility(View.VISIBLE);
            loadingView.stopLoading();
            return;
        }

        this.data = data;
        mainLayout.setVisibility(View.VISIBLE);
        if (tipText != null)
            tipText.setVisibility(View.INVISIBLE);
        setLoadingVisible(false);

        if (data.getIconUrl() != null) {
            if (SkyNetImageCache.getSkyNetImageCache().downloadUrl(data.getPkgName(),
                    data.getIconUrl(), this, SkyConstants.iconWidth,
                    SkyConstants.iconWidth))
                iconImage.setImageBitmap(null);
            else
                iconImage.setImageDrawable(SkinManager.getResDrawable(R.drawable.icon_default));
        } else {
            iconImage.setImageDrawable(SkinManager.getResDrawable(R.drawable.icon_default));
        }

        if (data.getCornerIcon() != null && data.getCornerIcon().trim().length() > 0) {
            if (cornerIconImage == null) {
                cornerIconImage = new CatchImageView(context);
                cornerIconImage.setScaleType(ScaleType.FIT_END);
            }
            if (cornerIconImage.getParent() == null) {
                LayoutParams cornerParmams = new LayoutParams(SkyConstants.cornerIconWidth,
                        SkyConstants.cornerIconWidth);
                int gap = (SkyConstants.cornerIconWidth - SkyConstants.iconWidth) / 2;
                cornerParmams.leftMargin = iconLeftMargin - gap;
                cornerParmams.topMargin = iconTopMargin - gap;
                mainLayout.addView(cornerIconImage, cornerParmams);
            }
            cornerIconImage.setImageBitmap(null);
            SkyNetImageCache.getSkyNetImageCache().downloadUrl("", data.getCornerIcon(), this, SkyConstants.iconWidth,
                    SkyConstants.iconWidth);
        } else {
            if (cornerIconImage != null && cornerIconImage.getParent() != null)
                cornerIconImage.setVisibility(View.INVISIBLE);
        }
        UICommon.setText(titleText, data.getTitle(), true);
        for (int i = 0; i < maxInfoSize; i++) {
            TextView infoText = null;
            if (i < infoLayout.getChildCount())
                infoText = (TextView) infoLayout.getChildAt(i);
            else {
                infoText = UICommon.newTextView(context, infoTextSize, R.color.detailInfoColor);
                infoText.setPadding(0, SkyConstants.Div(5), 0, SkyConstants.Div(5));
                infoText.setEllipsize(TruncateAt.END);
                infoLayout.addView(infoText, new LayoutParams(LayoutParams.MATCH_PARENT,
                        LayoutParams.WRAP_CONTENT));
            }
            if (data.getInfoList() != null && i < data.getInfoList().size())
                infoText.setText(data.getInfoList().get(i));
            else
                infoText.setText("");
        }
        statusIndicator.setData(data);
        statusIndicator.updateStatus(data.getAppStatus(), true);
        resetInfoWidth(data.getAppStatus());
        if (data.getAppStatus() == AppStatus.HAS_NEW_VERSION) {
            UICommon.setText(introductionText, data.getUpdateInfo() + "\n" + data.getIntroduction());
        } else {
            UICommon.setText(introductionText, data.getIntroduction());
        }

        shotsScroll.setShotsUrl(data.getScreenShotsPreview());
    }

    public void updateStatus(AppStatus status) {
        statusIndicator.updateStatus(status);
        resetInfoWidth(status);
    }

    private void resetInfoWidth(AppStatus status) {
        if (status == AppStatus.WAITING || status == AppStatus.DOWNLOADING
                || status == AppStatus.DOWNLOAD_PAUSED || status == AppStatus.INSTALLING) {
            FrameLayout.LayoutParams infoParams = (LayoutParams) infoLayout.getLayoutParams();
            infoParams.width = shortInfoWidth;
            infoLayout.setLayoutParams(infoParams);
        } else {
            FrameLayout.LayoutParams infoParams = (LayoutParams) infoLayout.getLayoutParams();
            infoParams.width = longInfoWidth;
            infoLayout.setLayoutParams(infoParams);
        }
    }

    public void updateDownloadPercent(int percent) {
        statusIndicator.updateDownloadPercent(percent);
    }

    Handler mainHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case UPDATE_ICON:
                    iconBitmap = (Bitmap) msg.obj;
                    try {
                        cornerBitmap = ImageUtils.getRoundedCornerBitmap(iconBitmap, 25);
                        iconImage.setImageBitmap(cornerBitmap);
                    } catch (Exception e) {
                        iconImage.setImageBitmap(iconBitmap);
                    }

                    if (introDialog != null && introDialog.isShowing()) {
                        introDialog.setImageIcon(cornerBitmap);
                    }
                    break;
                case UPDATE_CORNER_ICON:
                    Bitmap cornerBitmap = (Bitmap) msg.obj;

                    if (cornerIconImage != null) {
                        cornerIconImage.setImageBitmap(cornerBitmap);
                        cornerIconImage.setVisibility(View.VISIBLE);
                    }
                    break;
                case UPDATE_SHOT_BIG:
                    break;
                case UPDATE_SHOT_PREVIEW:
                    Bitmap bitmap = (Bitmap) msg.obj;
                    if (mDestory) {
                        if (bitmap != null && !bitmap.isRecycled()) {
                            bitmap.recycle();
                            bitmap = null;
                        }
                    } else {
                        shotsScroll.imageLoaded(msg.arg1, bitmap);
                    }
                    break;
            }
            super.handleMessage(msg);
        }
    };

    @Override
    public void loadFinished(String url, Bitmap result) {
        // TODO Auto-generated method stub
        if (result == null)
            LogUtils.d("shot", "loadFinished, url = " + url + ", shot == null");
        else
            LogUtils.d("shot", "loadFinished, url = " + url + ", shot != null");
        if (result == null)
            return;
        if (url.equals(data.getIconUrl())) {
            if (mDestory) {
                return;
            }
            Message msg = mainHandler.obtainMessage(UPDATE_ICON);
            msg.obj = result;
            mainHandler.sendMessage(msg);
            return;
        }
        if (data.getCornerIcon() != null && url.equals(data.getCornerIcon())) {
            if (mDestory) {
                return;
            }
            Message msg = mainHandler.obtainMessage(UPDATE_CORNER_ICON);
            msg.obj = result;
            mainHandler.sendMessage(msg);
            return;
        }
        for (int i = 0; i < data.getScreenShotsPreview().size(); i++) {
            String shotUrl = data.getScreenShotsPreview().get(i);
            if (url.equals(shotUrl)) {
                Message msg = mainHandler.obtainMessage(UPDATE_SHOT_PREVIEW);
                msg.arg1 = i;
                msg.obj = result;
                mainHandler.sendMessage(msg);
                break;
            }
        }
        for (int i = 0; i < data.getScreenShotsBig().size(); i++) {
            String shotUrl = data.getScreenShotsBig().get(i);
            if (url.equals(shotUrl)) {
                Message msg = mainHandler.obtainMessage(UPDATE_SHOT_BIG);
                msg.arg1 = i;
                msg.obj = result;
                mainHandler.sendMessage(msg);
                break;
            }
        }
    }

    private IntroductionDialog introDialog;
    private ShotDialog shotDialog;
    private OnClickListener imageClickListener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            int index = (Integer) v.getTag();
            if (shotDialog == null) {
                shotDialog = new ShotDialog(context);
                shotDialog.setPreviewListener(AppDetailView.this);
            }
            shotDialog.setContent(getBigShotUrl(), index);
            shotDialog.show();
        }
    };

    private List<String> getBigShotUrl() {
        if (CoocaaApplication.mDiv >= 1.0f) {
            if (data.getScreenShotsBig().size() > MAX_SHOT_COUNT)
                return data.getScreenShotsBig().subList(0, 5);
            return data.getScreenShotsBig();
        }
        if (data.getScreenShots().size() > MAX_SHOT_COUNT)
            return data.getScreenShots().subList(0, 5);
        return data.getScreenShots();
    }

    private void recycleBitmaps() {
        mDestory = true;
        shotsScroll.recycleBitmaps();
        if (introDialog != null) {
            introDialog.dismiss();
            introDialog = null;
        }
        if (shotDialog != null) {
            shotDialog.dismiss();
            shotDialog.destory();
            shotDialog = null;
        }
        iconImage.setImageBitmap(null);
        if (cornerIconImage != null) {
            cornerIconImage.setImageBitmap(null);
            cornerIconImage = null;
        }

        if (cornerBitmap != null && !cornerBitmap.isRecycled()) {
            cornerBitmap.recycle();
            cornerBitmap = null;
        }

        iconBitmap = null;
        statusIndicator.recycleBitmaps();
    }

    public void destory(){
        recycleBitmaps();
        if (mButtonLayer != null)
            mButtonLayer.onDestory();
    }

    @Override
    public Bitmap getBitmapByIndex(int index) {
        // TODO Auto-generated method stub
        return shotsScroll.getBitmapByIndex(index);
    }

    @Override
    public void loseFocus(int index) {
        // TODO Auto-generated method stub
        if (index >= 2)
            introductionText.requestFocus();
        else {
            statusIndicator.setBtnFocus(index == 0 ? true : false);
        }
    }
}
